/**
 * <p>Title: SMSModel.java</p>
 * <p>Description: </p>
 * <p>Copyright: Baosight Software LTD.co Copyright (c) 2002</p>
 * <p>Company: Baosight Software</p>
 * @author 张志芳
 * @version 1.0
 * <pre>Histroy:
 *          2012-6-28 上午07:39:57  张志芳  Create
 *</pre>
 */
package com.baosight.sczx.common.zm.cInterface.ct;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;

import com.baosight.iplat4j.dao.Dao;
import com.baosight.sczx.common.zm.basetools.StaticTools;
import com.baosight.sczx.common.zm.basetools.TablePk;
import com.baosight.sczx.zm.ct.domain.ZMCTSmsTimely;

/**
 * 短信模板接口
 * <p>Title: SMSModel.java</p>
 * <p>Description: </p>
 * <p>Copyright: Baosight Software LTD.co Copyright (c) 2002</p>
 * <p>Company: Baosight Software</p>
 * @author 张志芳
 * @version 1.0
 * <pre>Histroy:
 *          2012-6-28 上午07:39:57  张志芳  Create
 *</pre>
 */
public class SMSModel {
	private String beginSign = "$";
	private String endSign = "$";
	private String keyIdFieldName = "keyid";
	private String mobileNumFieldName = "mobilenum";
	private String sqlParamName = ":currentdate";
	private Dao dao;
	
	private IgenerateSms smsDevice;
	
	public SMSModel(Dao dao)
	{
		this.dao = dao;
		if("1".equals(SystemSet.getInstance().getFdSmsDevice()))
		{
			smsDevice=new SmsDeviceMasSetting();//mas机
		}
		else
		{
			smsDevice=new SmsDeviceCatSetting();//短信猫
		}
	}
	
	/**
	 * 根据模板新增一条定时消息
	 * <p>Function: insertRegularSMS</p>
	 * <p>Description: modelMap包含模板的所有字段, planSendTime模板中设置的发送时间</p>
	 * <p>return value:void</p>
	 * <p>throws Exception:</p>
	 * <p>History:
	 *    2012-6-28上午07:32:39 张志芳
	 * </p>
	 *
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void insertRegularSMS(Map modelMap, String planSendTime)throws Exception{ 
		String modelId = modelMap.get("fdKeyId").toString();
		String ds = modelMap.get("fdDs").toString();
		String sql = modelMap.get("fdSql").toString();
		String content = ""; 
		
		//解析模板内容
		List<Map<String, String>> datas = getQueryData(ds, sql);
		if(datas==null)
			return;		
		content = modelMap.get("fdModelContent").toString();//获取短信模板内容
		Map<String, String> paramMap = datas.get(0);//获取查询结果的第一条数据
		content = analyzeContent(content, paramMap);//转化模板内容中的参数
		
		
		//首先查询模板下设置的发送人员，并将它们拼接成以“；”隔开的字符串				
		List<String> person = getPerson(modelId);
		if(person==null)
			return;
		
		//新增一条短信
		Map row = new HashMap();
		row.put("fdKeyId", TablePk.getInstance().getNextValue("T_CT_SMS"));
		row.put("fdNo", person.get(0));
		row.put("fdName", person.get(1));
		row.put("fdMobilePhone", person.get(2));
		row.put("fdSmsContent", content);
		row.put("fdStatus", "未发送");
		row.put("fdCreateTime", StaticTools.getDateTime());
		row.put("fdModelId", modelId);
		row.put("fdIsTemporary", "否");
		row.put("fdPlanSendTime", planSendTime);
		dao.insert("ZMCTSms.insert", row);
	}
	
	/**
	 * 根据模板新增一条及时消息
	 * <p>Function: insertTimelySMS</p>
	 * <p>Description: modelMap包含模板的所有字段</p>
	 * <p>return value:void</p>
	 * <p>throws Exception:</p>
	 * <p>History:
	 *    2012-6-29上午07:42:56 张志芳
	 * </p>
	 *
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void insertTimelySMS(Map modelMap)throws Exception{
		String date = StaticTools.getDate();
		String modelId = modelMap.get("fdKeyId").toString();
		String ds = modelMap.get("fdDs").toString();
		String sql = modelMap.get("fdSql").toString();
		sql = ReplaceSqlParam(sql, date);//转化sql语句中的参数
		String content = ""; 
		
		//查询数据
		List<Map<String, String>> datas = getQueryData(ds, sql);
		if(datas==null)
			return;			
		
		Map map = new HashMap();
		map.put("fdDate", date);
		map.put("fdModelId", modelId);
		List<ZMCTSmsTimely> list = dao.query("ZMCTSmsTimely.query", map);
		
		content = modelMap.get("fdModelContent").toString();//获取短信模板内容
		for(Map<String, String> paramMap : datas)
		{	
			//判断该及时数据是否已经发送过(在T_CT_SMS_TIMELY表中查找数据主键是否已经存在
			Boolean flag = true;
			String keyid = paramMap.get(keyIdFieldName).trim();			
			for(ZMCTSmsTimely smsTimely : list)
			{
				if(keyid.equals(smsTimely.getFdSqlId().trim())) {
					flag = false;
					break;
				}
			}
			if(flag == false)
				break;
			
			content = analyzeContent(modelMap.get("fdModelContent").toString(), paramMap);//转化模板内容中的参数			
			String mobilePhone = paramMap.get(mobileNumFieldName);//获取手机号
			String createTime = StaticTools.getDateTime();
			
			//发送消息
			generateSMS(content, mobilePhone, createTime);
			
			//新增一条短信存档
			Map row = new HashMap();
			row.put("fdKeyId", TablePk.getInstance().getNextValue("T_CT_SMS"));
			row.put("fdNo", "");
			row.put("fdName", "");
			row.put("fdMobilePhone", mobilePhone);
			row.put("fdSmsContent", content);
			row.put("fdStatus", "已发送");
			row.put("fdCreateTime", createTime);
			row.put("fdModelId", modelId);
			row.put("fdIsTemporary", "否");
			row.put("fdSendTime", createTime);
			dao.insert("ZMCTSms.insert", row);		
			
			//将发过的及时数据在T_CT_SMS_TIMELY中记录
			row.clear();
			row.put("fdKeyId", TablePk.getInstance().getNextValue("T_CT_SMS_TIMELY"));
			row.put("fdModelId", modelId);
			row.put("fdSqlId", keyid);
			row.put("fdDate", date);
			dao.insert("ZMCTSmsTimely.insert", row);
		}				
	}
	
	/**
	 * 查询发送人的所有信息（包括工号，姓名，手机号）    只供定时消息用
	 * <p>Function: getPerson</p>
	 * <p>Description: </p>
	 * <p>return value:List<String>返回值有三个，第一个是工号，第二个是姓名，第三个是手机号</p>
	 * <p>throws Exception:</p>
	 * <p>History:
	 *    2012-6-29上午07:21:28 张志芳
	 * </p>
	 *
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private List<String> getPerson(String modelId)
	{
		Map param = new HashMap();
		param.put("fdModelId", modelId);
		List<Map> list = dao.query("ZMCTSmsModelPerson.queryByModel", param);
		if(list==null || list.size()<=0)//若没有设置人员，则返回空
			return null;
		String fdNo = "";
		String fdName = "";
		String fdMobilePhone = "";
		for(Map map : list)
		{
			fdNo += map.get("fdPersonNo")+";";
			fdName += map.get("fdPersonName")+";";
			fdMobilePhone += map.get("fdMobilePhone")+";";
		}
		fdNo = fdNo.substring(0, fdNo.length()-1);
		fdName = fdName.substring(0, fdName.length()-1);
		fdMobilePhone = fdMobilePhone.substring(0, fdMobilePhone.length()-1);
		
		List<String> result = new ArrayList<String>();
		result.add(fdNo);
		result.add(fdName);
		result.add(fdMobilePhone);
		return result;
	}	
	
	/**
	 * 解析模板内容中的参数
	 * <p>Function: analyzeContent</p>
	 * <p>Description: </p>
	 * <p>return value:String</p>
	 * <p>throws Exception:</p>
	 * <p>History:
	 *    2012-6-29上午05:55:57 张志芳
	 * </p>
	 *
	 */
	private String analyzeContent(String content, Map<String, String> paramMap){
		for(String key : paramMap.keySet())
		{
			content = content.replaceAll(Matcher.quoteReplacement(beginSign + key + endSign), paramMap.get(key));
		}
		return content;
	}
	
	/**
	 * 查询模板中的sql数据
	 * <p>Function: getQueryData</p>
	 * <p>Description: </p>
	 * <p>return value:List<Map<String, String>></p>
	 * <p>throws Exception:</p>
	 * <p>History:
	 *    2012-6-29上午06:21:33 张志芳
	 * </p>
	 *
	 */
	private List<Map<String, String>> getQueryData(String ds, String sql)throws Exception{
		DataInterface datainterface = new DataInterface(ds);
		ResultSet rs = datainterface.query(sql);				
		if(rs != null)
		{	
			List<Map<String, String>> list = new ArrayList<Map<String, String>>();
			while(rs.next()){
				//遍历rs的所有列，取出所有字段对应的值，组成Map
				Map<String, String> paramMap = new HashMap<String, String>();   
				ResultSetMetaData rsmd = rs.getMetaData();   
				int count = rsmd.getColumnCount();   
				for (int i = 1; i <= count; i++) {   
					String key = rsmd.getColumnName(i);   
					String value = rs.getString(key);   
					paramMap.put(key.toLowerCase(), value);   
				} 
				list.add(paramMap);
			}
			return list;
		}
		datainterface.colseDs();
		return null;
	}
	
	/**
	 * 将T_CT_SMS中存储的信息转换成List——一个号码一条短信
	 * <p>Function: getSmsList</p>
	 * <p>Description: </p>
	 * <p>return value:List<Map></p>
	 * <p>throws Exception:</p>
	 * <p>History:
	 *    2012-7-2上午01:54:59 张志芳
	 * </p>
	 *
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private List<Map> getSmsList(String content, String mobilePhone, String createTime)
	{
		List<Map> smslist = new ArrayList<Map>();
		String[] nums = mobilePhone.split(";");			
		for(int i=0; i<nums.length; i++)
		{
			Map smsmap = new HashMap();
			smsmap.put("content", content);
			smsmap.put("mobileNum", nums[i]);
			smsmap.put("createTime", createTime);
			smslist.add(smsmap);
		}
		return smslist;
	}
	
	/**
	 * 将短信发给短信猫或者MAS机处理
	 * <p>Function: generateSMS</p>
	 * <p>Description: </p>
	 * <p>return value:void</p>
	 * <p>throws Exception:</p>
	 * <p>History:
	 *    2012-7-3上午03:34:01 张志芳
	 * </p>
	 *
	 */
	public void generateSMS(String content, String mobilePhone, String createTime)
	{
		smsDevice.generateSms(getSmsList(content, mobilePhone, createTime));
	}
	
	/**
	 * 将sql语句中的参数替换成实际值
	 * <p>Function: ReplaceSqlParam</p>
	 * <p>Description: </p>
	 * <p>return value:String</p>
	 * <p>throws Exception:</p>
	 * <p>History:
	 *    2012-7-5上午06:15:55 张志芳
	 * </p>
	 *
	 */
	private String ReplaceSqlParam(String sql, String date)
	{
		return sql.replaceAll(Matcher.quoteReplacement(sqlParamName), date);
	}
}
